// File: jmcomic-core/src/main/java/dev/jukomu/common/util/json/JsonUtils.java
package dev.jukomu.common.util.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import dev.jukomu.common.util.file.FileUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class JsonUtils {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        // Pretty print JSON by default for better readability
        MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
        // Disable writing dates as timestamps
        MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }

    /**
     * 将JSON字符串解析为Map。
     *
     * @param jsonString JSON字符串
     * @return 解析后的Map
     * @throws IOException 如果解析失败
     */
    public static Map<String, Object> parseStringAsMap(String jsonString) throws JsonProcessingException {
        return MAPPER.readValue(jsonString, new TypeReference<Map<String, Object>>() {
        });
    }

    /**
     * 将JSON字符串解析为List。
     *
     * @param jsonString JSON字符串
     * @return 解析后的List
     * @throws IOException 如果解析失败
     */
    public static List<String> parseStringAsList(String jsonString) throws JsonProcessingException {
        return MAPPER.readValue(jsonString, new TypeReference<List<String>>() {
        });
    }

    /**
     * 将JSON字符串解析为指定类型。
     *
     * @param jsonString JSON字符串
     * @param valueType  要解析的类型
     * @param <T>        类型参数
     * @return 解析后的对象
     * @throws IOException 如果解析失败
     */
    public static <T> T parseString(String jsonString, Class<T> valueType) throws IOException {
        return MAPPER.readValue(jsonString, valueType);
    }

    /**
     * 从文件中加载JSON并解析为Map。
     *
     * @param file JSON文件
     * @return 解析后的Map
     * @throws IOException 如果加载或解析失败
     */
    public static Map<String, Object> loadFileAsMap(File file) throws IOException {
        return MAPPER.readValue(file, new TypeReference<Map<String, Object>>() {
        });
    }

    /**
     * 从输入流加载JSON并解析为Map。
     *
     * @param inputStream 输入流
     * @return 解析后的Map
     * @throws IOException 如果加载或解析失败
     */
    public static Map<String, Object> loadInputStreamAsMap(InputStream inputStream) throws IOException {
        return MAPPER.readValue(inputStream, new TypeReference<Map<String, Object>>() {
        });
    }

    /**
     * 将对象序列化为JSON字符串。
     *
     * @param obj 要序列化的对象
     * @return JSON字符串
     * @throws IOException 如果序列化失败
     */
    public static String toJsonString(Object obj) throws IOException {
        return MAPPER.writeValueAsString(obj);
    }

    /**
     * 将对象序列化为格式化（美化）的JSON字符串。
     *
     * @param obj 要序列化的对象
     * @return 格式化后的JSON字符串
     * @throws IOException 如果序列化失败
     */
    public static String toPrettyJsonString(Object obj) throws IOException {
        return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
    }

    /**
     * 将对象写入到JSON文件。
     *
     * @param file 要写入的文件
     * @param obj  要序列化的对象
     * @throws IOException 如果写入失败
     */
    public static void writeObjectToFile(File file, Object obj) throws IOException {
        FileUtils.getDirPath(file.getAbsolutePath(), true); // Ensure parent directory exists
        MAPPER.writeValue(file, obj);
    }

    /**
     * 将对象写入到JSON输出流。
     *
     * @param outputStream 输出流
     * @param obj          要序列化的对象
     * @throws IOException 如果写入失败
     */
    public static void writeObjectToOutputStream(OutputStream outputStream, Object obj) throws IOException {
        MAPPER.writeValue(outputStream, obj);
    }


    /**
     * 遍历JSON数据中的所有键。
     *
     * @param data JSON数据（可以是Map、List或基本类型）
     * @return 所有键的Stream
     */
    public static Stream<String> keysOfJson(Object data) {
        if (data instanceof Map) {
            Map<?, ?> map = (Map<?, ?>) data;
            return Stream.concat(
                    map.keySet().stream().map(String::valueOf),
                    map.values().stream().flatMap(JsonUtils::keysOfJson)
            );
        } else if (data instanceof List) {
            List<?> list = (List<?>) data;
            return list.stream().flatMap(JsonUtils::keysOfJson);
        }
        return Stream.empty();
    }

    /**
     * 遍历JSON数据中的所有值。
     *
     * @param data JSON数据（可以是Map、List或基本类型）
     * @return 所有值的Stream
     */
    public static Stream<Object> valuesOfJson(Object data) {
        if (data instanceof Map) {
            Map<?, ?> map = (Map<?, ?>) data;
            return map.values().stream().flatMap(JsonUtils::valuesOfJson);
        } else if (data instanceof List) {
            List<?> list = (List<?>) data;
            return list.stream().flatMap(JsonUtils::valuesOfJson);
        } else {
            return Stream.of(data);
        }
    }

    /**
     * 判断字符串是否为Map
     *
     * @param str
     * @return
     */
    public static boolean isMapStringByJackson(String str) {
        try {
            new ObjectMapper().readTree(str).isObject(); // 检查是否为 JSON Object
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断字符串是否为List
     *
     * @param str
     * @return
     */
    public static boolean isListStringByJackson(String str) {
        try {
            new ObjectMapper().readTree(str).isArray(); // 检查是否为 JSON Array
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}